<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="../book.css" charset="ISO-8859-1"
	type="text/css">
<title>Merge</title>
</head>
<body>
<h1>Merge</h1>
<p>
    This function is initiated via the <span class="menu">Team &gt; Merge </span> menu
    option.
</p>
<p>
    <img src="../images/bullet-important.png" width="85" height="16" align="left">Branching
    and merging within SVN can become quite complex and so it is recommended
    that you gain a thorough understanding of the concepts before you start using
    it. The chapter on <a
	href="http://svnbook.red-bean.com/en/1.1/ch04.html" target="_top"> <i>Branching
    and Merging</i> </a> in the <a href="http://svnbook.red-bean.com/"
	target="_top"> <i>Subversion Book</i></a> provides a detailed description of
    the concepts as well as many examples of how branching and merging can be
    used.
</p>
<h2>Overview</h2>
<p>
    Where branches are used to maintain separate lines of development, at some
        stage you will want to <span class="action">merge</span> the changes
        made on one branch back into the trunk, or vice versa.
</p>
<p>
    The merge process works by generating a list of differences between two points
    in the repository, and applying those differences to your <a href="glossary.html#working">working
    copy</a>. For example if you want to merge the changes made in revision N
    then you have to compare revision N with revision (N-1). Novices often ask, &#8220;Why
    do I have to subtract 1 from the start revision.&#8221; Think of the underlying
    Diff process and it will become clearer. To make this easier, when you use <span class="control">Show
    Log</span> to select a range of revisions to merge, the SVN plug-in for Eclipse
    makes this adjustment for you automatically.
</p>
<p>
    <img src="../images/bullet-warn.png" width="75" height="16" align="left">If
    you have made changes in your working copy, commit those changes first before
    executing the merge. Otherwise, if the merge does not go as you expect, you
    may want to <a href="revert.html">Revert</a> the merged result. In this scenario,
    the revert command will discard <em>all</em> changes including any you had
    made before the merge. The only exception to this is files which are <em>added</em> to
    your working copy by the merge process. When you initiate a revert and there
    are additions in your working copy, those files are not removed. Instead
    they become unversioned files in your working copy, and you have to manually
    delete them before you attempt the merge again.
</p>
<h2>Process</h2>
<p>
    <img src="../images/merge-dialog.png" width="575" height="477">
</p>
<p>
    There are two common use cases for merging which are handled in slightly
        different ways. These are discussed below.
</p>
<h3>Merging a Range of Revisions</h3>
<p>
    This method covers the case when you have made one or more revisions to a
        branch (or to the trunk) and you want to port those changes across to
        a different branch. To merge revisions you need to <a href="switch.html">Switch</a> to
        a working copy of the branch in which you want to receive the changes,
        often the trunk. Select <span class="menu">Merge...</span> from the Team
        context menu.
</p>
<ol type="1">
    <li>
        <p>
            In the <span class="control">From:</span> field enter the full folder
            URL of the branch or tag containing the changes you want to port
            into your working copy. You may also click <span class="control">Browse...</span> to
            browse the repository and find the desired branch. If you have merged
            from this branch before, then just use the drop down list which shows
            a history of previously used URLs.
        </p>
    </li>
    <li>
        <p>
            Because you are porting a range of revisions from the same branch
                into your working copy, make sure the <span class="control">Use "From:" URL</span> check
                box is <span class="action">checked</span>.
        </p>
    </li>
    <li>
        <p>
            In the <span class="control">From Revision</span> field, enter the
            start revision number. This is the revision <em>before</em> the changes
            you want to merge. Remember that SVN will create a diff file in order
            to perform the merge, so the start point has to be just before the
            first change you are interested in. For example, your log messages
            may look something like this:
        </p>
        <span class="code">Rev Comments<br>
        39. Working on MyBranch <br>
        38. Working on trunk <br>
        37. Working on MyBranch <br>
        36. Create branch MyBranch <br>
        35. Working on trunk <br>
        34. Working on trunk <br>
        ... </span>
        <p>
            If you now want to merge all of the changes from MyBranch into the
                trunk you have to choose 36 as the From Revision, not 37 as you
                might think. If you select revision 37 as the start point, then
                the difference engine compares the end point with revision 37,
                and will miss the changes made in revision 37 itself. If that
                sounds complicated, don't worry, there is an easier way with
                the SVN plug-in for Eclipse ...
        </p>
        <p>
            The easiest way to select the range of revisions you need is to click
                on <span class="control">Show Log</span>, as this will list recent
                changes with their log comments. If you want to merge the changes
                from a single revision, just select that revision. If you want
                to merge changes from several revisions, then select that range
                (using the usual <em>Shift</em>-modifier). Click on <span class="control">OK</span> and
                the revision numbers of the From revision and To revision in
                the Merge dialog will <em>both</em> be filled in for you.
        </p>
        <p>
            If you have already merged some changes from this branch, hopefully
                you will have made a note of the last revision merged in the
                message when you committed the change. In that case, you can
                use <span class="control">Show Log</span> for the working copy
                to trace that log message. Use the end point of the last merge
                as the start point for this merge. For example, if you have merged
                revisions 37 to 39 last time, then the start point for this merge
                should be revision 39.
        </p>
    </li>
    <li>
        <p>
            If you have not used <span class="control">Show Log</span> to select
            the revision range, then you will need to set the <span class="control">To
            Revision</span> manually. Enter the last revision number in the range
            you want to merge. Often this will be the HEAD revision, although
            it doesn't need to be - you may just want to merge a single revision.
        </p>
        <p>
            If other people may be committing changes then be careful about using
                the HEAD revision. It may not refer to the revision you think
                it does if someone else made a commit after your last update.
        </p>
    </li>
    <li>
        <p>
            Click <span class="control">OK</span> to complete the merge.
        </p>
    </li>
</ol>
<p>
    It is a good idea to have a look at the merge result and see if it is as
        you expected. Merging is usually quite complicated. Conflicts often arise
        if the branch has drifted far from the trunk.
</p>
<p>
    When you have tested the changes and come to commit this revision, your commit
        message should <em>always</em> include the revision numbers which have
        been ported in the merge. If you want to apply another merge at a later
        time you will need to know what you have already merged, as you do not
        want to port a change more than once. Unfortunately merge information
        is not stored by SVN. For more information about this, refer to <a
	href="http://svnbook.red-bean.com/en/1.1/ch04s03.html#svn-ch-4-sect-3.2.1"
	target="_top"> Tracking Merges Manually</a> in the <a
	href="http://svnbook.red-bean.com/" target="_top">Subversion Book</a>. Branch
        management is important. If you want to keep a branch up to date with
        the trunk, you should be sure to merge often so that the branch and trunk
        do not drift too far apart. Of course, you should still avoid the repeated
        merging of changes, as explained above.
</p>
<blockquote>
    <p>
        <img src="../images/bullet-important.png" width="85" height="16" align="left">SVN
        can't merge a file with a folder and vice versa - only folders to folders
        and files to files. If you click on a file and open up the merge dialog,
        then you have to give a path to a file in that dialog. If you select
        a folder and bring up the dialog, then you must specify a folder URL
        for the merge.
    </p>
</blockquote>
<h3>Merging Two Different Trees</h3>
<p>
    This method covers the case when you have made a feature branch. All trunk
    changes have been ported to the feature branch, week by week, and now the
    feature is complete you want to merge it back into the trunk. Because you
    have kept the feature branch synchronized with the trunk, the latest versions
    of branch and trunk will be absolutely identical except for your branch changes.
    So in this special case, you would merge by comparing the branch with the
    trunk.
</p>
<p>
    To merge the feature branch back into the trunk you need to go to a working
        copy of the trunk. Select <span class="menu">Merge...</span> from the
        context menu.
</p>
<ol type="1">
    <li>
        <p>
            In the <span class="control">From:</span> field enter the full folder
            URL of the <em>trunk</em>. This may sound wrong, but remember that
            the trunk is the start point to which you want to add the branch
            changes. You may also click <span class="control">Browse...</span> to
            browse the repository.
        </p>
    </li>
    <li>
        <p>
            Because you are comparing two different trees, make sure the <span class="control">Use "From:" URL</span> check
            box is <em>not</em> checked.
        </p>
    </li>
    <li>
        <p>
            In the <span class="control">To:</span> field enter the full folder
            URL of the feature branch.
        </p>
    </li>
    <li>
        <p>
            In both the <span class="control">From Revision</span> field and
            the <span class="control">To Revision</span> field, enter the last
            revision number at which the two trees were synchronized. If you
            are sure no-one else is making commits you can use the HEAD revision
            in both cases. If there is a chance that someone else may have made
            a commit since that synchronization, use the specific revision number
            to avoid losing more recent commits.
        </p>
        <p>
            You can also use <span class="control">Show Log</span> to select
            the revision. Note that in this case you are not selecting a range
            of revisions, so the revision you select there is what will actually
            appear in the Revision field.
        </p>
    </li>
    <li>
        <p>
            Click <span class="control">OK</span> to complete the merge.
        </p>
    </li>
</ol>
<p>
    In this case you will not need the feature branch again because the new feature
        is now integrated into the trunk. The feature branch is redundant and
        can be deleted from the repository if required.
</p>
<h3>Previewing Merge Results</h3>
<p>
    If you are uncertain about the possible outcome of a merge operation, you
    may want to preview what will happen before you allow it to change your working
    copy. There are two additional buttons to help you in this respect.
</p>
<p>
    <span class="control">Unified Diff</span> creates the diff file (remember
    that merge is based on diff) and shows you which lines will be changed in
    your working copy files. As this is a <a href="glossary.html#unified">unified
    diff</a> (patch) file it is not always easy to read out of context, but for
    small scale changes it is often helpful.
</p>
<p>
    Bare in mind that <span class="name">merge</span> and <span class="name">diff</span> are
    not exactly the same. Merge is smarter and knows how to take into account
    things like renames and moves. Diff always just shows the end result. Conceptually,
    they are very similar, but you cannot always just apply a unified diff to
    a working copy and get the same results as merge.
</p>
<p>
    <span class="control">Dry Run</span> performs the merge operation, but does <em>not</em> modify
    the working copy at all. It shows you a list of the files that will be changed
    by a real merge, and notes those areas where conflicts will occur. This information
    is shown in the <a href="svn-console.html"><span class="name">SVN Console
    View</span></a>.
</p>
<h3>Undoing changes with Merge</h3>
<p>
    Another common use for merge is to roll back a change that has already been
    committed. Suppose you are coding in a working copy of <span class="filefolder">/calc/trunk</span>,
    and you discover that the change made way back in revision 303, which changed <span class="filefolder">integer.c</span>,
    is completely wrong; it never should have been committed. You can use merge to <span class="action">undo</span> the
    change in your working copy, and then commit the local modification to the
    repository. All you need to do is to specify a <em>reverse</em> difference:
</p>
<span class="code">$ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk <br>
U integer.c <br>
$ svn status <br>
M integer.c <br>
$ svn diff ... <br>
# verify that the change is removed ... <br>
$ svn commit -m "Undoing change committed in r303." <br>
Sending integer.c <br>
Transmitting file data. <br>
Committed revision 350. </span>
<p>
    One way to think about a repository revision is as a specific group of changes
    (some version control systems call these <em>changesets</em>). By using the <span class="filefolder">-r</span> switch,
    you can ask <span class="name">svn merge</span> to apply a changeset, or
    whole range of changesets, to your working copy. In our case of undoing a
    change, we're asking <span class="name">svn merge</span> to apply changeset
    303 to our working copy <em>backwards</em>.
</p>
<p>
    Keep in mind that rolling back a change like this is just like any other <span class="name">svn
    merge</span> operation, so you should use <span class="name">svn status</span> and <span class="name">svn
    diff</span> to confirm that your work is in the state you want it to be in,
    and then use <span class="name">svn commit</span> to send the final version
    to the repository. After committing, this particular changeset is no longer
    reflected in the HEAD revision.
</p>
<p>
    Again, you may be thinking: well, that really didn't undo the commit, did
        it? The change still exists in revision 303. If somebody checks out a
        version of the <span class="filefolder">calc</span> project between revisions
        303 and 349, they'll still see the bad change, right?
</p>
<p>
    Yes, that's true. When we talk about <em>removing</em> a change, we're really
    talking about removing it from HEAD. The
    original change still exists in the repository's history. For most situations,
    this is good enough. Most people are only interested in tracking the HEAD of
    a project anyway. There are special cases, however, where you really might
    want to destroy all evidence of the commit. (Perhaps somebody accidentally
    committed a confidential document.) This isn't so easy, it turns out, because
    SVN was deliberately designed to never lose information. Revisions are immutable
    trees which build upon one another. Removing a revision from history would
    cause a domino effect, creating chaos in all subsequent revisions and possibly
    invalidating all working copies.
</p>
<p class="tasks">
    Related Tasks
</p>
<p>
    <a href="../dailywork/branches.html">Maintaining branches with SVN </a><br />
    <a href="../reference/configure-tags.html">Configure Branches/Tags </a>
</p>
<p class="reference">
    Related Reference
</p>
<p>
    <a href="revert.html"> </a> <a href="revert.html">Revert</a><br>
    <a href="switch.html">Switch</a>
</p>
</body>
</html>
